package com.cashmama.market.api.domain.oss;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.AssumeRoleResult;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.cashmama.market.api.infras.config.ApolloConfigUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.InputStream;

/**
 * @program: market-api
 * @description
 * @author: frank
 * @create: 2020-09-24 18:10
 **/
@Service
public class AmazonS3TokenService {

    @Autowired
    private ApolloConfigUtil apolloConfigUtil;

    public AmazonS3TokenInfo assumeRole(String userCode){

        // Creating the STS client is part of your trusted code. It has
        // the security credentials you use to obtain temporary security credentials.
        AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(apolloConfigUtil.getAmazonAccessKeyId(), apolloConfigUtil.getAmazonAccessKeySecret())))
                .withRegion(apolloConfigUtil.getAmazonRegion())
                .build();

        // Obtain credentials for the IAM role. Note that you cannot assume the role of an AWS root account;
        // Amazon S3 will deny access. You must use credentials for an IAM user or an IAM role.
        AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                .withRoleArn(apolloConfigUtil.getAmazonAccessRoleArn())
                .withRoleSessionName(userCode);
        AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);

        String objectName = apolloConfigUtil.isServerTest() ? "moveClientSpace/test/" + userCode : "moveClientSpace/" + userCode;

        return AmazonS3TokenInfo.translate(roleResponse, apolloConfigUtil.getAmazonS3BaseUrl(), apolloConfigUtil.getAmazonBucketName(), objectName, apolloConfigUtil.getAmazonRegion());
    }

    public static class AmazonS3TokenInfo{

        private String accessKeyId;
        private String accessKeySecret;
        private String securityToken;
        private String region;
        private String expiration;
        private String objectName;
        private String bucketName;
        private String baseUrl;

        public static AmazonS3TokenInfo translate(AssumeRoleResult roleResponse, String baseUrl, String bucketName, String objectName, String region) {

            AmazonS3TokenInfo amazonS3TokenInfo = new AmazonS3TokenInfo();
            amazonS3TokenInfo.setAccessKeyId(roleResponse.getCredentials().getAccessKeyId());
            amazonS3TokenInfo.setAccessKeySecret(roleResponse.getCredentials().getSecretAccessKey());
            amazonS3TokenInfo.setSecurityToken(roleResponse.getCredentials().getSessionToken());
            amazonS3TokenInfo.setExpiration(String.valueOf(roleResponse.getCredentials().getExpiration().getTime()));
            amazonS3TokenInfo.setBaseUrl(baseUrl);
            amazonS3TokenInfo.setBucketName(bucketName);
            amazonS3TokenInfo.setObjectName(objectName);
            amazonS3TokenInfo.setRegion(region);

            return amazonS3TokenInfo;
        }

        public String getRegion() {
            return region;
        }

        public AmazonS3TokenInfo setRegion(String region) {
            this.region = region;
            return this;
        }

        public String getAccessKeyId() {
            return accessKeyId;
        }

        public AmazonS3TokenInfo setAccessKeyId(String accessKeyId) {
            this.accessKeyId = accessKeyId;
            return this;
        }

        public String getAccessKeySecret() {
            return accessKeySecret;
        }

        public AmazonS3TokenInfo setAccessKeySecret(String accessKeySecret) {
            this.accessKeySecret = accessKeySecret;
            return this;
        }

        public String getSecurityToken() {
            return securityToken;
        }

        public AmazonS3TokenInfo setSecurityToken(String securityToken) {
            this.securityToken = securityToken;
            return this;
        }

        public String getExpiration() {
            return expiration;
        }

        public AmazonS3TokenInfo setExpiration(String expiration) {
            this.expiration = expiration;
            return this;
        }

        public String getObjectName() {
            return objectName;
        }

        public AmazonS3TokenInfo setObjectName(String objectName) {
            this.objectName = objectName;
            return this;
        }

        public String getBucketName() {
            return bucketName;
        }

        public AmazonS3TokenInfo setBucketName(String bucketName) {
            this.bucketName = bucketName;
            return this;
        }

        public String getBaseUrl() {
            return baseUrl;
        }

        public AmazonS3TokenInfo setBaseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
            return this;
        }
    }

    public static void main(String[] args) {
        // Creating the STS client is part of your trusted code. It has
        // the security credentials you use to obtain temporary security credentials.
        AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("AKIAWUCLRELHUB4CFU6I", "ifmvbwQ8fR7cKC0Y6S3hWTLfj8p9XSjwq5yEK1K7")))
                .withRegion("ap-south-1")
                .build();

        // Obtain credentials for the IAM role. Note that you cannot assume the role of an AWS root account;
        // Amazon S3 will deny access. You must use credentials for an IAM user or an IAM role.
        AssumeRoleRequest roleRequest = new AssumeRoleRequest()
                .withRoleArn("arn:aws:iam::455424942799:role/AssumeRole")
                .withRoleSessionName("0987654345678900987655673338");
        AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
        System.out.println(JSONObject.toJSONString(roleResponse));

        Credentials sessionCredentials = roleResponse.getCredentials();

        // Create a BasicSessionCredentials object that contains the credentials you just retrieved.
        BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
                sessionCredentials.getAccessKeyId(),
                sessionCredentials.getSecretAccessKey(),
                sessionCredentials.getSessionToken());

        // Provide temporary security credentials so that the Amazon S3 client
        // can send authenticated requests to Amazon S3. You create the client
        // using the sessionCredentials object.
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion("ap-south-1")
                .build();
//        ObjectMetadata meta = new ObjectMetadata();
//        PutObjectRequest request = new PutObjectRequest("cashmama-fat2", "test123123123", inputStream, meta);
//        // 设置公共读取
//        request.withCannedAcl(CannedAccessControlList.PublicRead);
//        s3Client.putObject(request);
        // Verify that assuming the role worked and the permissions are set correctly
        // by getting a set of object keys from the bucket.
        ObjectListing objects = s3Client.listObjects("cashmama-fat2");
        System.out.println("No. of Objects: " + objects.getObjectSummaries().size());
        OSSClient client = new OSSClient("http://oss-ap-south-1.aliyuncs.com", "LTAI4FgSMcfMBpXavW7iuPpM", "mrJeZyMvjH06kz1FqxugnaFqduBczi");
        OSSObject ossObject = client.getObject("cashmama-fat2", "clientSpace/test/2020030299008171001300/d70af4f7-0f51-44fe-97b7-2678479aa9a1");
        InputStream inputStream = ossObject.getObjectContent();
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType("image/jpeg");
        PutObjectRequest request = new PutObjectRequest("cashmama-fat2", "d70af4f7-3", inputStream, objectMetadata);
        // 设置公共读取
        request.withCannedAcl(CannedAccessControlList.PublicRead);
        // 上传文件
        PutObjectResult putObjectResult = s3Client.putObject(request);
        System.out.println(JSONObject.toJSONString(putObjectResult));

    }
}
